{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.embeddings.dashscope import DashScopeEmbeddings\n",
    "from langchain.vectorstores.chroma import Chroma\n",
    "from langchain.llms.tongyi import Tongyi\n",
    "from dotenv import load_dotenv\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "load_dotenv()\n",
    "api_key = os.environ.get(\"DASHSCOPE_API_KEY\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一、加载向量数据库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_2640/672964056.py:3: LangChainDeprecationWarning: The class `Chroma` was deprecated in LangChain 0.2.9 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-chroma package and should be used instead. To use it run `pip install -U :class:`~langchain-chroma` and import as `from :class:`~langchain_chroma import Chroma``.\n",
      "  vectordb = Chroma(persist_directory=persist_directory,embedding_function=embedding)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "29\n"
     ]
    }
   ],
   "source": [
    "persist_directory = \"./docs/chroma/matplotlib/\"\n",
    "embedding = DashScopeEmbeddings(dashscope_api_key=api_key)\n",
    "vectordb = Chroma(persist_directory=persist_directory,embedding_function=embedding)\n",
    "print(vectordb._collection.count())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "question = \"这节课的主要话题是什么？\"\n",
    "docs = vectordb.similarity_search(question)\n",
    "print(len(docs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二、构建检索式问答链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这节课的主要话题是 **Matplotlib 的基本使用**，包括：\n",
      "\n",
      "1. 认识 Matplotlib：作为 Python 2D 绘图库的基本功能和应用场景。\n",
      "2. 一个最简单的绘图例子：通过 `pyplot.subplots()` 创建 figure 和 axes，并使用 `ax.plot()` 绘制折线图。\n",
      "3. 两种绘图接口的对比：介绍 **面向对象（OO）模式** 和 **pyplot 模式** 的区别与用法。\n",
      "4. 绘图模板的讲解：以 OO 模式为例展示通用绘图模板。\n",
      "5. 思考题：分析两种绘图模式的优缺点及适用场景，并要求写出一个 pyplot 模式的简单绘图模板。\n",
      "\n",
      "此外，课程还涉及使用 `np.random.randn(2, 150)` 生成数据并绘制散点图与边际分布图，进一步实践非均匀子图布局的实现。\n"
     ]
    }
   ],
   "source": [
    "from langchain.chains import RetrievalQA\n",
    "\n",
    "llm = Tongyi(model=\"qwen-flash\", api_key=api_key)\n",
    "# 声明一个检索式问答链\n",
    "qa_chain = RetrievalQA.from_llm(llm, retriever = vectordb.as_retriever())\n",
    "\n",
    "question = \"这节课的主要话题是什么？\"\n",
    "result = qa_chain.invoke({\"query\":question})\n",
    "print(result[\"result\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 三、深入探究检索式问答链"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.1 基于模板的检索式问答链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts import PromptTemplate\n",
    "\n",
    "template = \"\"\"\n",
    "使用以下上下文片段来回答最后的问题。如果你不知道答案，只需要说不知道，不要试图编造答案。答案最多使用三个句子。尽量简明扼要地回答问题。在回答的最后一定要说\"感谢你的提问！\"\n",
    "{context}\n",
    "问题：\n",
    "{question}\n",
    "有用的问答：\n",
    "\"\"\"\n",
    "QA_CHAIN_PROMPOT = PromptTemplate.from_template(template)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 基于该模板来构建检索式问答链\n",
    "qa_chain = RetrievalQA.from_chain_type(\n",
    "    llm,\n",
    "    retriever = vectordb.as_retriever(),\n",
    "    return_source_documents=True,\n",
    "    chain_type_kwargs={\"prompt\":QA_CHAIN_PROMPOT}\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这门课主要学习使用Python进行数据可视化，特别是基于Matplotlib库的绘图技术。课程内容涉及Python代码编写和数据可视化实践，因此会使用Python。  \n",
      "感谢你的提问！\n"
     ]
    }
   ],
   "source": [
    "question = \"这门课会学习Python吗？\"\n",
    "result = qa_chain.invoke(question)\n",
    "print(result[\"result\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "page_content='第⼀回： Matplotlib 初相识\n",
      "⼀、认识 matplotlib \n",
      "Matplotlib 是⼀个 Python 2D 绘图库，能够以多种硬拷⻉格式和跨平台的交互式环境⽣成出版物质量的图形，⽤来绘制各种\n",
      "静态，动态，交互式的图表。\n",
      "Matplotlib 可⽤于 Python 脚本， Python 和 IPython Shell 、 Jupyter notebook ， Web 应⽤程序服务器和各种图形⽤⼾界⾯⼯具\n",
      "包等。\n",
      "Matplotlib 是 Python 数据可视化库中的泰⽃，它已经成为 python 中公认的数据可视化⼯具，我们所熟知的 pandas 和 seaborn\n",
      "的绘图接⼝其实也是基于 matplotlib 所作的⾼级封装。\n",
      "为了对 matplotlib 有更好的理解，让我们从⼀些最基本的概念开始认识它，再逐渐过渡到⼀些⾼级技巧中。\n",
      "⼆、⼀个最简单的绘图例⼦\n",
      "Matplotlib 的图像是画在 figure （如 windows ， jupyter 窗体）上的，每⼀个 figure ⼜包含了⼀个或多个 axes （⼀个可以指定坐\n",
      "标系的⼦区域）。最简单的创建 figure 以及 axes 的⽅式是通过pyplot.subplots命令，创建 axes 以后，可以使⽤Axes.plot绘制\n",
      "最简易的折线图。\n",
      "import matplotlib.pyplot as plt\n",
      "import matplotlib as mpl\n",
      "import numpy as np\n",
      "fig, ax = plt.subplots()  # 创建一个包含一个 axes 的 figure\n",
      "ax.plot([1, 2, 3, 4], [1, 4, 2, 3]);  # 绘制图像\n",
      "T r ick ：  在 jupyter notebook 中使⽤ matplotlib 时会发现，代码运⾏后⾃动打印出类似<matplotlib.lines.Line2D at\n",
      "0x23155916dc0>这样⼀段话，这是因为 matplotlib 的绘图代码默认打印出最后⼀个对象。如果不想显⽰这句话，有以下三种\n",
      "⽅法，在本章节的代码⽰例中你能找到这三种⽅法的使⽤。\n",
      "1. 在代码块最后加⼀个分号;\n",
      "2. 在代码块最后加⼀句 plt.show()\n",
      "3. 在绘图时将绘图对象显式赋值给⼀个变量，如将 plt.plot([1, 2, 3, 4]) 改成 line =plt.plot([1, 2, 3, 4])\n",
      "和 MATLAB 命令类似，你还可以通过⼀种更简单的⽅式绘制图像，matplotlib.pyplot⽅法能够直接在当前 axes 上绘制图像，\n",
      "如果⽤⼾未指定 axes ， matplotlib 会帮你⾃动创建⼀个。所以上⾯的例⼦也可以简化为以下这⼀⾏代码。\n",
      "line =plt.plot([1, 2, 3, 4], [1, 4, 2, 3]) \n",
      " Contents \n",
      "⼀、认识 matplotlib\n",
      "⼆、⼀个最简单的绘图例⼦\n",
      "三、 Figure 的组成\n",
      "四、两种绘图接⼝\n",
      "五、通⽤绘图模板\n",
      "思考题\n",
      "P r i n t  t o P D F' metadata={'total_pages': 4, 'producer': 'Skia/PDF m141', 'creationdate': '2025-10-07T13:45:02+00:00', 'title': '第一回：Matplotlib初相识 — fantastic-matplotlib', 'creator': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0', 'page': 0, 'page_label': '1', 'moddate': '2025-10-07T13:45:02+00:00', 'source': '../data/第一回：Matplotlib初相识.pdf'}\n"
     ]
    }
   ],
   "source": [
    "print(result[\"source_documents\"][0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.2 基于MapReduce的检索式问答链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "expected str, bytes or os.PathLike object, not NoneType",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[15]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m      1\u001b[39m qa_chain_mr = RetrievalQA.from_chain_type(\n\u001b[32m      2\u001b[39m     llm,\n\u001b[32m      3\u001b[39m     retriever=vectordb.as_retriever(),\n\u001b[32m      4\u001b[39m     chain_type=\u001b[33m\"\u001b[39m\u001b[33mmap_reduce\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m      5\u001b[39m )\n\u001b[32m      7\u001b[39m question = \u001b[33m\"\u001b[39m\u001b[33m这门课会学习Python吗？\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m result = \u001b[43mqa_chain_mr\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquestion\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m      9\u001b[39m \u001b[38;5;28mprint\u001b[39m(result[\u001b[33m\"\u001b[39m\u001b[33mresult\u001b[39m\u001b[33m\"\u001b[39m])\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/base.py:165\u001b[39m, in \u001b[36mChain.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m    162\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m    163\u001b[39m     \u001b[38;5;28mself\u001b[39m._validate_inputs(inputs)\n\u001b[32m    164\u001b[39m     outputs = (\n\u001b[32m--> \u001b[39m\u001b[32m165\u001b[39m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    166\u001b[39m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[32m    167\u001b[39m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m._call(inputs)\n\u001b[32m    168\u001b[39m     )\n\u001b[32m    170\u001b[39m     final_outputs: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Any] = \u001b[38;5;28mself\u001b[39m.prep_outputs(\n\u001b[32m    171\u001b[39m         inputs,\n\u001b[32m    172\u001b[39m         outputs,\n\u001b[32m    173\u001b[39m         return_only_outputs,\n\u001b[32m    174\u001b[39m     )\n\u001b[32m    175\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/retrieval_qa/base.py:159\u001b[39m, in \u001b[36mBaseRetrievalQA._call\u001b[39m\u001b[34m(self, inputs, run_manager)\u001b[39m\n\u001b[32m    157\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m    158\u001b[39m     docs = \u001b[38;5;28mself\u001b[39m._get_docs(question)  \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m159\u001b[39m answer = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcombine_documents_chain\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    160\u001b[39m \u001b[43m    \u001b[49m\u001b[43minput_documents\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    161\u001b[39m \u001b[43m    \u001b[49m\u001b[43mquestion\u001b[49m\u001b[43m=\u001b[49m\u001b[43mquestion\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    162\u001b[39m \u001b[43m    \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_run_manager\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    163\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    165\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.return_source_documents:\n\u001b[32m    166\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[38;5;28mself\u001b[39m.output_key: answer, \u001b[33m\"\u001b[39m\u001b[33msource_documents\u001b[39m\u001b[33m\"\u001b[39m: docs}\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/_api/deprecation.py:190\u001b[39m, in \u001b[36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m    188\u001b[39m     warned = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m    189\u001b[39m     emit_warning()\n\u001b[32m--> \u001b[39m\u001b[32m190\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/base.py:632\u001b[39m, in \u001b[36mChain.run\u001b[39m\u001b[34m(self, callbacks, tags, metadata, *args, **kwargs)\u001b[39m\n\u001b[32m    627\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(args[\u001b[32m0\u001b[39m], callbacks=callbacks, tags=tags, metadata=metadata)[\n\u001b[32m    628\u001b[39m         _output_key\n\u001b[32m    629\u001b[39m     ]\n\u001b[32m    631\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[32m--> \u001b[39m\u001b[32m632\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m[\n\u001b[32m    633\u001b[39m         _output_key\n\u001b[32m    634\u001b[39m     ]\n\u001b[32m    636\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[32m    637\u001b[39m     msg = (\n\u001b[32m    638\u001b[39m         \u001b[33m\"\u001b[39m\u001b[33m`run` supported with either positional arguments or keyword arguments,\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m    639\u001b[39m         \u001b[33m\"\u001b[39m\u001b[33m but none were provided.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m    640\u001b[39m     )\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/_api/deprecation.py:190\u001b[39m, in \u001b[36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m    188\u001b[39m     warned = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m    189\u001b[39m     emit_warning()\n\u001b[32m--> \u001b[39m\u001b[32m190\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/base.py:410\u001b[39m, in \u001b[36mChain.__call__\u001b[39m\u001b[34m(self, inputs, return_only_outputs, callbacks, tags, metadata, run_name, include_run_info)\u001b[39m\n\u001b[32m    378\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Execute the chain.\u001b[39;00m\n\u001b[32m    379\u001b[39m \n\u001b[32m    380\u001b[39m \u001b[33;03mArgs:\u001b[39;00m\n\u001b[32m   (...)\u001b[39m\u001b[32m    401\u001b[39m \u001b[33;03m        `Chain.output_keys`.\u001b[39;00m\n\u001b[32m    402\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m    403\u001b[39m config = {\n\u001b[32m    404\u001b[39m     \u001b[33m\"\u001b[39m\u001b[33mcallbacks\u001b[39m\u001b[33m\"\u001b[39m: callbacks,\n\u001b[32m    405\u001b[39m     \u001b[33m\"\u001b[39m\u001b[33mtags\u001b[39m\u001b[33m\"\u001b[39m: tags,\n\u001b[32m    406\u001b[39m     \u001b[33m\"\u001b[39m\u001b[33mmetadata\u001b[39m\u001b[33m\"\u001b[39m: metadata,\n\u001b[32m    407\u001b[39m     \u001b[33m\"\u001b[39m\u001b[33mrun_name\u001b[39m\u001b[33m\"\u001b[39m: run_name,\n\u001b[32m    408\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m410\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    411\u001b[39m \u001b[43m    \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    412\u001b[39m \u001b[43m    \u001b[49m\u001b[43mcast\u001b[49m\u001b[43m(\u001b[49m\u001b[43mRunnableConfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43mk\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    413\u001b[39m \u001b[43m    \u001b[49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[43m=\u001b[49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    414\u001b[39m \u001b[43m    \u001b[49m\u001b[43minclude_run_info\u001b[49m\u001b[43m=\u001b[49m\u001b[43minclude_run_info\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    415\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/base.py:165\u001b[39m, in \u001b[36mChain.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m    162\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m    163\u001b[39m     \u001b[38;5;28mself\u001b[39m._validate_inputs(inputs)\n\u001b[32m    164\u001b[39m     outputs = (\n\u001b[32m--> \u001b[39m\u001b[32m165\u001b[39m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    166\u001b[39m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[32m    167\u001b[39m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m._call(inputs)\n\u001b[32m    168\u001b[39m     )\n\u001b[32m    170\u001b[39m     final_outputs: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Any] = \u001b[38;5;28mself\u001b[39m.prep_outputs(\n\u001b[32m    171\u001b[39m         inputs,\n\u001b[32m    172\u001b[39m         outputs,\n\u001b[32m    173\u001b[39m         return_only_outputs,\n\u001b[32m    174\u001b[39m     )\n\u001b[32m    175\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/combine_documents/base.py:143\u001b[39m, in \u001b[36mBaseCombineDocumentsChain._call\u001b[39m\u001b[34m(self, inputs, run_manager)\u001b[39m\n\u001b[32m    141\u001b[39m \u001b[38;5;66;03m# Other keys are assumed to be needed for LLM prediction\u001b[39;00m\n\u001b[32m    142\u001b[39m other_keys = {k: v \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m inputs.items() \u001b[38;5;28;01mif\u001b[39;00m k != \u001b[38;5;28mself\u001b[39m.input_key}\n\u001b[32m--> \u001b[39m\u001b[32m143\u001b[39m output, extra_return_dict = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcombine_docs\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    144\u001b[39m \u001b[43m    \u001b[49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    145\u001b[39m \u001b[43m    \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_run_manager\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    146\u001b[39m \u001b[43m    \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mother_keys\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    147\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    148\u001b[39m extra_return_dict[\u001b[38;5;28mself\u001b[39m.output_key] = output\n\u001b[32m    149\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m extra_return_dict\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/combine_documents/map_reduce.py:253\u001b[39m, in \u001b[36mMapReduceDocumentsChain.combine_docs\u001b[39m\u001b[34m(self, docs, token_max, callbacks, **kwargs)\u001b[39m\n\u001b[32m    247\u001b[39m question_result_key = \u001b[38;5;28mself\u001b[39m.llm_chain.output_key\n\u001b[32m    248\u001b[39m result_docs = [\n\u001b[32m    249\u001b[39m     Document(page_content=r[question_result_key], metadata=docs[i].metadata)\n\u001b[32m    250\u001b[39m     \u001b[38;5;66;03m# This uses metadata from the docs, and the textual results from `results`\u001b[39;00m\n\u001b[32m    251\u001b[39m     \u001b[38;5;28;01mfor\u001b[39;00m i, r \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(map_results)\n\u001b[32m    252\u001b[39m ]\n\u001b[32m--> \u001b[39m\u001b[32m253\u001b[39m result, extra_return_dict = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mreduce_documents_chain\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcombine_docs\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    254\u001b[39m \u001b[43m    \u001b[49m\u001b[43mresult_docs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    255\u001b[39m \u001b[43m    \u001b[49m\u001b[43mtoken_max\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken_max\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    256\u001b[39m \u001b[43m    \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    257\u001b[39m \u001b[43m    \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    258\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    259\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.return_intermediate_steps:\n\u001b[32m    260\u001b[39m     intermediate_steps = [r[question_result_key] \u001b[38;5;28;01mfor\u001b[39;00m r \u001b[38;5;129;01min\u001b[39;00m map_results]\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/combine_documents/reduce.py:255\u001b[39m, in \u001b[36mReduceDocumentsChain.combine_docs\u001b[39m\u001b[34m(self, docs, token_max, callbacks, **kwargs)\u001b[39m\n\u001b[32m    233\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcombine_docs\u001b[39m(\n\u001b[32m    234\u001b[39m     \u001b[38;5;28mself\u001b[39m,\n\u001b[32m    235\u001b[39m     docs: \u001b[38;5;28mlist\u001b[39m[Document],\n\u001b[32m   (...)\u001b[39m\u001b[32m    238\u001b[39m     **kwargs: Any,\n\u001b[32m    239\u001b[39m ) -> \u001b[38;5;28mtuple\u001b[39m[\u001b[38;5;28mstr\u001b[39m, \u001b[38;5;28mdict\u001b[39m]:\n\u001b[32m    240\u001b[39m \u001b[38;5;250m    \u001b[39m\u001b[33;03m\"\"\"Combine multiple documents recursively.\u001b[39;00m\n\u001b[32m    241\u001b[39m \n\u001b[32m    242\u001b[39m \u001b[33;03m    Args:\u001b[39;00m\n\u001b[32m   (...)\u001b[39m\u001b[32m    253\u001b[39m \u001b[33;03m        element returned is a dictionary of other keys to return.\u001b[39;00m\n\u001b[32m    254\u001b[39m \u001b[33;03m    \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m255\u001b[39m     result_docs, extra_return_dict = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_collapse\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    256\u001b[39m \u001b[43m        \u001b[49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    257\u001b[39m \u001b[43m        \u001b[49m\u001b[43mtoken_max\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken_max\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    258\u001b[39m \u001b[43m        \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    259\u001b[39m \u001b[43m        \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    260\u001b[39m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    261\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.combine_documents_chain.combine_docs(\n\u001b[32m    262\u001b[39m         docs=result_docs,\n\u001b[32m    263\u001b[39m         callbacks=callbacks,\n\u001b[32m    264\u001b[39m         **kwargs,\n\u001b[32m    265\u001b[39m     )\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/combine_documents/reduce.py:310\u001b[39m, in \u001b[36mReduceDocumentsChain._collapse\u001b[39m\u001b[34m(self, docs, token_max, callbacks, **kwargs)\u001b[39m\n\u001b[32m    308\u001b[39m result_docs = docs\n\u001b[32m    309\u001b[39m length_func = \u001b[38;5;28mself\u001b[39m.combine_documents_chain.prompt_length\n\u001b[32m--> \u001b[39m\u001b[32m310\u001b[39m num_tokens = \u001b[43mlength_func\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult_docs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    312\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_collapse_docs_func\u001b[39m(docs: \u001b[38;5;28mlist\u001b[39m[Document], **kwargs: Any) -> \u001b[38;5;28mstr\u001b[39m:\n\u001b[32m    313\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._collapse_chain.run(\n\u001b[32m    314\u001b[39m         input_documents=docs,\n\u001b[32m    315\u001b[39m         callbacks=callbacks,\n\u001b[32m    316\u001b[39m         **kwargs,\n\u001b[32m    317\u001b[39m     )\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/combine_documents/stuff.py:242\u001b[39m, in \u001b[36mStuffDocumentsChain.prompt_length\u001b[39m\u001b[34m(self, docs, **kwargs)\u001b[39m\n\u001b[32m    240\u001b[39m inputs = \u001b[38;5;28mself\u001b[39m._get_inputs(docs, **kwargs)\n\u001b[32m    241\u001b[39m prompt = \u001b[38;5;28mself\u001b[39m.llm_chain.prompt.format(**inputs)\n\u001b[32m--> \u001b[39m\u001b[32m242\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mllm_chain\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_get_num_tokens\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain/chains/llm.py:426\u001b[39m, in \u001b[36mLLMChain._get_num_tokens\u001b[39m\u001b[34m(self, text)\u001b[39m\n\u001b[32m    425\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_get_num_tokens\u001b[39m(\u001b[38;5;28mself\u001b[39m, text: \u001b[38;5;28mstr\u001b[39m) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m426\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_language_model\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mllm\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_num_tokens\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/language_models/base.py:377\u001b[39m, in \u001b[36mBaseLanguageModel.get_num_tokens\u001b[39m\u001b[34m(self, text)\u001b[39m\n\u001b[32m    365\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mget_num_tokens\u001b[39m(\u001b[38;5;28mself\u001b[39m, text: \u001b[38;5;28mstr\u001b[39m) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m    366\u001b[39m \u001b[38;5;250m    \u001b[39m\u001b[33;03m\"\"\"Get the number of tokens present in the text.\u001b[39;00m\n\u001b[32m    367\u001b[39m \n\u001b[32m    368\u001b[39m \u001b[33;03m    Useful for checking if an input fits in a model's context window.\u001b[39;00m\n\u001b[32m   (...)\u001b[39m\u001b[32m    375\u001b[39m \n\u001b[32m    376\u001b[39m \u001b[33;03m    \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m377\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_token_ids\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/language_models/base.py:363\u001b[39m, in \u001b[36mBaseLanguageModel.get_token_ids\u001b[39m\u001b[34m(self, text)\u001b[39m\n\u001b[32m    361\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.custom_get_token_ids \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m    362\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.custom_get_token_ids(text)\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_token_ids_default_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/language_models/base.py:79\u001b[39m, in \u001b[36m_get_token_ids_default_method\u001b[39m\u001b[34m(text)\u001b[39m\n\u001b[32m     77\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Encode the text into token IDs.\"\"\"\u001b[39;00m\n\u001b[32m     78\u001b[39m \u001b[38;5;66;03m# get the cached tokenizer\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m79\u001b[39m tokenizer = \u001b[43mget_tokenizer\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m     81\u001b[39m \u001b[38;5;66;03m# tokenize the text using the GPT-2 tokenizer\u001b[39;00m\n\u001b[32m     82\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m tokenizer.encode(text)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/langchain_core/language_models/base.py:73\u001b[39m, in \u001b[36mget_tokenizer\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m     71\u001b[39m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mImportError\u001b[39;00m(msg) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m     72\u001b[39m \u001b[38;5;66;03m# create a GPT-2 tokenizer instance\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m73\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mGPT2TokenizerFast\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_pretrained\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mgpt2\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:2070\u001b[39m, in \u001b[36mPreTrainedTokenizerBase.from_pretrained\u001b[39m\u001b[34m(cls, pretrained_model_name_or_path, cache_dir, force_download, local_files_only, token, revision, trust_remote_code, *init_inputs, **kwargs)\u001b[39m\n\u001b[32m   2067\u001b[39m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m   2068\u001b[39m         logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mloading file \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfile_path\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m from cache at \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresolved_vocab_files[file_id]\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m2070\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_from_pretrained\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m   2071\u001b[39m \u001b[43m    \u001b[49m\u001b[43mresolved_vocab_files\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2072\u001b[39m \u001b[43m    \u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2073\u001b[39m \u001b[43m    \u001b[49m\u001b[43minit_configuration\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2074\u001b[39m \u001b[43m    \u001b[49m\u001b[43m*\u001b[49m\u001b[43minit_inputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2075\u001b[39m \u001b[43m    \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2076\u001b[39m \u001b[43m    \u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2077\u001b[39m \u001b[43m    \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2078\u001b[39m \u001b[43m    \u001b[49m\u001b[43m_commit_hash\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcommit_hash\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2079\u001b[39m \u001b[43m    \u001b[49m\u001b[43m_is_local\u001b[49m\u001b[43m=\u001b[49m\u001b[43mis_local\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2080\u001b[39m \u001b[43m    \u001b[49m\u001b[43mtrust_remote_code\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtrust_remote_code\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2081\u001b[39m \u001b[43m    \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2082\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:2108\u001b[39m, in \u001b[36mPreTrainedTokenizerBase._from_pretrained\u001b[39m\u001b[34m(cls, resolved_vocab_files, pretrained_model_name_or_path, init_configuration, token, cache_dir, local_files_only, _commit_hash, _is_local, trust_remote_code, *init_inputs, **kwargs)\u001b[39m\n\u001b[32m   2105\u001b[39m \u001b[38;5;66;03m# If one passes a GGUF file path to `gguf_file` there is no need for this check as the tokenizer will be\u001b[39;00m\n\u001b[32m   2106\u001b[39m \u001b[38;5;66;03m# loaded directly from the GGUF file.\u001b[39;00m\n\u001b[32m   2107\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (from_slow \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m has_tokenizer_file) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mcls\u001b[39m.slow_tokenizer_class \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m gguf_file:\n\u001b[32m-> \u001b[39m\u001b[32m2108\u001b[39m     slow_tokenizer = \u001b[43m(\u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mslow_tokenizer_class\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_from_pretrained\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m   2109\u001b[39m \u001b[43m        \u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m.\u001b[49m\u001b[43mdeepcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresolved_vocab_files\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2110\u001b[39m \u001b[43m        \u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2111\u001b[39m \u001b[43m        \u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m.\u001b[49m\u001b[43mdeepcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43minit_configuration\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2112\u001b[39m \u001b[43m        \u001b[49m\u001b[43m*\u001b[49m\u001b[43minit_inputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2113\u001b[39m \u001b[43m        \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2114\u001b[39m \u001b[43m        \u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2115\u001b[39m \u001b[43m        \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2116\u001b[39m \u001b[43m        \u001b[49m\u001b[43m_commit_hash\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_commit_hash\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2117\u001b[39m \u001b[43m        \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m.\u001b[49m\u001b[43mdeepcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   2118\u001b[39m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m   2119\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m   2120\u001b[39m     slow_tokenizer = \u001b[38;5;28;01mNone\u001b[39;00m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:2316\u001b[39m, in \u001b[36mPreTrainedTokenizerBase._from_pretrained\u001b[39m\u001b[34m(cls, resolved_vocab_files, pretrained_model_name_or_path, init_configuration, token, cache_dir, local_files_only, _commit_hash, _is_local, trust_remote_code, *init_inputs, **kwargs)\u001b[39m\n\u001b[32m   2314\u001b[39m \u001b[38;5;66;03m# Instantiate the tokenizer.\u001b[39;00m\n\u001b[32m   2315\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m2316\u001b[39m     tokenizer = \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43minit_inputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43minit_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m   2317\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m import_protobuf_decode_error():\n\u001b[32m   2318\u001b[39m     logger.info(\n\u001b[32m   2319\u001b[39m         \u001b[33m\"\u001b[39m\u001b[33mUnable to load tokenizer model from SPM, loading from TikToken will be attempted instead.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m   2320\u001b[39m         \u001b[33m\"\u001b[39m\u001b[33m(Google protobuf error: Tried to load SPM model with non-SPM vocab file).\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m   2321\u001b[39m     )\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/code/AIAgent_learning/Langchain-learning/.venv/lib/python3.12/site-packages/transformers/models/gpt2/tokenization_gpt2.py:153\u001b[39m, in \u001b[36mGPT2Tokenizer.__init__\u001b[39m\u001b[34m(self, vocab_file, merges_file, errors, unk_token, bos_token, eos_token, pad_token, add_prefix_space, add_bos_token, **kwargs)\u001b[39m\n\u001b[32m    149\u001b[39m pad_token = AddedToken(pad_token, lstrip=\u001b[38;5;28;01mFalse\u001b[39;00m, rstrip=\u001b[38;5;28;01mFalse\u001b[39;00m) \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(pad_token, \u001b[38;5;28mstr\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m pad_token\n\u001b[32m    151\u001b[39m \u001b[38;5;28mself\u001b[39m.add_bos_token = add_bos_token\n\u001b[32m--> \u001b[39m\u001b[32m153\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvocab_file\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mutf-8\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m vocab_handle:\n\u001b[32m    154\u001b[39m     \u001b[38;5;28mself\u001b[39m.encoder = json.load(vocab_handle)\n\u001b[32m    155\u001b[39m \u001b[38;5;28mself\u001b[39m.decoder = {v: k \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m.encoder.items()}\n",
      "\u001b[31mTypeError\u001b[39m: expected str, bytes or os.PathLike object, not NoneType"
     ]
    }
   ],
   "source": [
    "qa_chain_mr = RetrievalQA.from_chain_type(\n",
    "    llm,\n",
    "    retriever=vectordb.as_retriever(),\n",
    "    chain_type=\"map_reduce\"\n",
    ")\n",
    "\n",
    "question = \"这门课会学习Python吗？\"\n",
    "result = qa_chain_mr.invoke(question)\n",
    "print(result[\"result\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.3 基于Refine的检索式问答链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "是的，这门课会学习Python。\n",
      "\n",
      "课程内容以 **Matplotlib** 为核心，而 Matplotlib 是 Python 生态中最重要的 2D 绘图库之一。从教学内容可见，课程大量使用 Python 语法和相关工具，例如：  \n",
      "- 使用 `import matplotlib.pyplot as plt` 导入绘图模块；  \n",
      "- 结合 `numpy` 进行数据处理；  \n",
      "- 在 Jupyter Notebook 环境中运行代码，这是 Python 数据科学常用的工作流；  \n",
      "- 通过 `plt.subplots()`、`ax.plot()` 等方式操作图形对象，体现了对 Python 面向对象编程的理解与应用。\n",
      "\n",
      "此外，课程强调 Matplotlib 是 pandas 和 seaborn 等高级可视化库的基础，这些库均基于 Python 构建。因此，本课程不仅会介绍 Matplotlib 的使用，更会深入讲解其背后的 Python 编程机制，意味着学生必须掌握 Python 基础知识才能顺利学习和实践。\n",
      "\n",
      "在课程的“思考题”部分，也明确要求对比 **Pyplot 模式** 与 **面向对象（OO）模式** 的优缺点，并编写一个基于 pyplot 模式的绘图模板，这进一步说明课程不仅涉及 Python 的使用，还要求学生理解不同编程范式在可视化中的实际应用。\n",
      "\n",
      "综上所述，这门课是以 Python 为语言基础，围绕数据可视化展开的教学，**必然包含对 Python 的学习与应用**，并在此基础上深入探讨绘图模式的设计与选择。\n"
     ]
    }
   ],
   "source": [
    "qa_chain_rf = RetrievalQA.from_chain_type(\n",
    "    llm,\n",
    "    retriever=vectordb.as_retriever(),\n",
    "    chain_type=\"refine\"\n",
    ")\n",
    "question = \"这门课会学习Python吗？\"\n",
    "result = qa_chain_rf.invoke({\"query\":question})\n",
    "print(result[\"result\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
